#include <fstream>
#include <boost/filesystem/path.hpp>
#include <iostream>
#include <string>
#include <stdio.h>
#include <math.h>
#include "../panda/components/CmdLine/cmdargs.h"
#include "../panda/components/perlutil.h"
#include "get_arg.h"
using std::string;
using std::ofstream;
using std::ifstream;
using std::cerr;
using std::cout;





//_______________________________________________________________________________________

//		GetArguments

//				from command line
//				Created [9/13/2001]

//_______________________________________________________________________________________
bool GetArguments(int argc, char* argv[], t_program_args& args)
{
	// optional help directive
	CmdArgUsage opt_help('h', "help", 	"display this message", &cout);

	// required options
	const unsigned REQUIRED = CmdArg::isREQ | CmdArg::isVALREQ;
	CmdArgStr opt_dbname('d', "dbname", "<string>",
								"PostgreSQL database name. ", REQUIRED);

	CmdArgStr opt_description ('d', "description", "<string>",
							"A short description of this operation.");
	CmdArgStr opt_sql_file ('f', "sql_file", "<string>",
							"file with SQL commands strings terminated by semicolons"
							" (default is stdout)");
	CmdArgStr opt_host	('h', "host", "<string>",
								"PostgreSQL database host computer address. ");
	CmdArgStr opt_user	('u', "user", "<string>",
								"PostgreSQL database user name. Defaults to 'postgres'.");
	CmdArgStr opt_password('p', "password", "<string>",
								"PostgreSQL database password.");

	CmdArgStr opt_err_log ('e', "err_log", "<string>",
								"file for logging errors "
								"(defaults to STDERR).");
	CmdArgSet opt_vacuum('s', "stats",
								 "recalibrate database stats for (possibly) faster queries.");
	CmdArgSet opt_verbose('v', "verbose",
								"issue lots more messages.");


	string exe_file_name =  boost::filesystem::path(*argv).leaf();



		// construct command line
	CmdLine  cmdline(exe_file_name.c_str(),
							&opt_dbname,
							&opt_host,
							&opt_user,
							&opt_password,
							&opt_sql_file,
							&opt_description,
							&opt_err_log,
							&opt_vacuum,
							&opt_verbose,
							&opt_help,
							0);

	// parse command line
	CmdArgvIter  argv_iter(--argc, ++argv);
	cmdline.description( "This program synchronizes the Panda SQL Database after "
							"updates to a sequence database."   );
	if (cmdline.parse(argv_iter))
		return false;

	// define verbose first before any error messages generated
	args.verbose	= opt_verbose;


	// make sure the error log file is valid
	string err_log		= opt_err_log.str();
	args.log_to_file = err_log.length();
	if (args.log_to_file)
	{
		args.f_err_log.open(err_log.c_str(), std::ios_base::out | std::ios_base::ate);
		if (!args.f_err_log.good())
		{
			cerr << "ERROR!! Could not open the error log file (" << err_log << ").\n";
			return(false);
		}
		args.f_err_log.setf(std::ios_base::unitbuf);
	}





	// initialize postgresql login
	string dbname	= "dbname=" +opt_dbname.str();
	string host		= opt_host;
	if (host.length())
		host = "host=" + host;
	string password = opt_password;
	if (password.length())
		password = "password=" + password;
	string user		= opt_user;
	if (!user.length())
		user = "postgres";
	user = "user=" + user;
	args.db_login = dbname + ' ' + host + ' ' + password + ' ' + user;


	// misc options
	args.vacuum 			= opt_vacuum;



	// sql file commands
	{
		string sql_file = opt_sql_file;
		std::ifstream is;
		std::istream* p_is;
		if (sql_file.length())
		{
			is.open(sql_file.c_str());
			if (!is.good())
			{
				cerr << "ERROR!!\tCould not open the SQL commands file (" << sql_file << ").\n";
				return(false);
			}
			p_is = &is;
		}
		else
		{
			args.VERBOSE() << "\tReading SQL commands from STDIN...\n";
			p_is = &std::cin;
		}
		string line;
		string sql_commands;
		while (std::getline(*p_is, line))
			sql_commands += line;
		if (sql_commands.length())
			perl_split(sql_commands, ";", args.sql_commands);
		if (!args.sql_commands.size())
		{
			cerr << "ERROR!! No SQL commands were specified.\n";
			return(false);
		}
	}

	// operation description
	args.description		= opt_description;


	return true;
}




